home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-M68K / IDE.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  12KB  |  469 lines

  1. /*
  2.  *  linux/include/asm-m68k/ide.h
  3.  *
  4.  *  Copyright (C) 1994-1996  Linus Torvalds & authors
  5.  */
  6.  
  7. /* Copyright(c) 1996 Kars de Jong */
  8. /* Based on the ide driver from 1.2.13pl8 */
  9.  
  10. /*
  11.  * Credits (alphabetical):
  12.  *
  13.  *  - Bjoern Brauel
  14.  *  - Kars de Jong
  15.  *  - Torsten Ebeling
  16.  *  - Dwight Engen
  17.  *  - Thorsten Floeck
  18.  *  - Roman Hodek
  19.  *  - Guenther Kelleter
  20.  *  - Chris Lawrence
  21.  *  - Michael Rausch
  22.  *  - Christian Sauer
  23.  *  - Michael Schmitz
  24.  *  - Jes Soerensen
  25.  *  - Michael Thurm
  26.  *  - Geert Uytterhoeven
  27.  */
  28.  
  29. #ifndef _M68K_IDE_H
  30. #define _M68K_IDE_H
  31.  
  32. #ifdef __KERNEL__
  33.  
  34. #include <linux/config.h>
  35.  
  36. #include <asm/setup.h>
  37. #include <asm/io.h>
  38. #include <asm/irq.h>
  39.  
  40. #ifdef CONFIG_ATARI
  41. #include <asm/atari_stdma.h>
  42. #endif
  43.  
  44. #ifdef CONFIG_MAC
  45. #include <asm/macints.h>
  46. #endif
  47.  
  48. typedef unsigned char * ide_ioreg_t;
  49.  
  50. #ifndef MAX_HWIFS
  51. #define MAX_HWIFS    4    /* same as the other archs */
  52. #endif
  53.  
  54. static __inline int ide_default_irq (ide_ioreg_t base)
  55. {
  56.     return 0;
  57. }
  58.  
  59. /*
  60.  *  Can we do this in a generic manner??
  61.  */
  62. static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
  63. {
  64.     printk("ide_init_hwif_ports: must not be called\n");
  65. }
  66.  
  67. typedef union {
  68.     unsigned all            : 8;    /* all of the bits together */
  69.     struct {
  70.         unsigned bit7        : 1;    /* always 1 */
  71.         unsigned lba        : 1;    /* using LBA instead of CHS */
  72.         unsigned bit5        : 1;    /* always 1 */
  73.         unsigned unit        : 1;    /* drive select number, 0 or 1 */
  74.         unsigned head        : 4;    /* always zeros here */
  75.     } b;
  76.     } select_t;
  77.  
  78. #ifdef CONFIG_MAC    /* MSch: Hack; wrapper for ide_intr */
  79. void mac_ide_intr(int irq, void *dev_id, struct pt_regs *regs);
  80. #endif
  81.  
  82. static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
  83.             unsigned long flags, const char *device, void *dev_id)
  84. {
  85. #ifdef CONFIG_AMIGA
  86.     if (MACH_IS_AMIGA)
  87.         return request_irq(irq, handler, 0, device, dev_id);
  88. #endif /* CONFIG_AMIGA */
  89. #ifdef CONFIG_MAC
  90.     if (MACH_IS_MAC)
  91. #if 0    /* MSch Hack: maybe later we'll call ide_intr without a wrapper */
  92.     return nubus_request_irq(12, dev_id, handler);
  93. #else
  94.     return nubus_request_irq(12, dev_id, mac_ide_intr);
  95. #endif
  96. #endif /* CONFIG_MAC */
  97.     return 0;
  98. }
  99.  
  100. static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
  101. {
  102. #ifdef CONFIG_AMIGA
  103.     if (MACH_IS_AMIGA)
  104.         free_irq(irq, dev_id);
  105. #endif /* CONFIG_AMIGA */
  106. #ifdef CONFIG_MAC
  107.     if (MACH_IS_MAC)
  108.         nubus_free_irq(12);
  109. #endif /* CONFIG_MAC */
  110. }
  111.  
  112. /*
  113.  * We should really implement those some day.
  114.  */
  115. static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
  116. {
  117.     return 0;
  118. }
  119.  
  120. static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name)
  121. {
  122. }
  123.  
  124. static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent)
  125. {
  126. }
  127.  
  128. #undef SUPPORT_SLOW_DATA_PORTS
  129. #define SUPPORT_SLOW_DATA_PORTS 0
  130.  
  131. #undef SUPPORT_VLB_SYNC
  132. #define SUPPORT_VLB_SYNC 0
  133.  
  134. #undef HD_DATA
  135. #define HD_DATA NULL
  136.  
  137. #define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
  138. #define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
  139.  
  140. #define insw(port, buf, nr) ({                \
  141.     unsigned char *_port = (unsigned char *)(port);    \
  142.     unsigned char *_buf = (buf);            \
  143.     int _nr = (nr);                    \
  144.     unsigned long _tmp;                \
  145.                             \
  146.     if (_nr & 15) {                    \
  147.         _tmp = (_nr & 15) - 1;            \
  148.         asm volatile (                \
  149.             "1: movew %2@,%0@+; dbra %1,1b"    \
  150.             : "=a" (_buf), "=d" (_tmp)    \
  151.             : "a" (_port), "0" (_buf),    \
  152.               "1" (_tmp));            \
  153.     }                        \
  154.     if (_nr >> 4) {                    \
  155.         _tmp = (_nr >> 4) - 1;            \
  156.         asm volatile (                \
  157.             "1: "                \
  158.             "movew %2@,%0@+; "        \
  159.             "movew %2@,%0@+; "        \
  160.             "movew %2@,%0@+; "        \
  161.             "movew %2@,%0@+; "        \
  162.             "movew %2@,%0@+; "        \
  163.             "movew %2@,%0@+; "        \
  164.             "movew %2@,%0@+; "        \
  165.             "movew %2@,%0@+; "        \
  166.             "movew %2@,%0@+; "        \
  167.             "movew %2@,%0@+; "        \
  168.             "movew %2@,%0@+; "        \
  169.             "movew %2@,%0@+; "        \
  170.             "movew %2@,%0@+; "        \
  171.             "movew %2@,%0@+; "        \
  172.             "movew %2@,%0@+; "        \
  173.             "movew %2@,%0@+; "        \
  174.             "dbra %1,1b"            \
  175.             : "=a" (_buf), "=d" (_tmp)    \
  176.             : "a" (_port), "0" (_buf),    \
  177.               "1" (_tmp));            \
  178.     }                        \
  179. })
  180.  
  181. #define outsw(port, buf, nr) ({                \
  182.     unsigned char *_port = (unsigned char *)(port);    \
  183.     unsigned char *_buf = (buf);            \
  184.     int _nr = (nr);                    \
  185.     unsigned long _tmp;                \
  186.                             \
  187.     if (_nr & 15) {                    \
  188.         _tmp = (_nr & 15) - 1;            \
  189.         asm volatile (                \
  190.             "1: movew %0@+,%2@; dbra %1,1b"    \
  191.             : "=a" (_buf), "=d" (_tmp)    \
  192.             : "a" (_port), "0" (_buf),    \
  193.               "1" (_tmp));            \
  194.     }                        \
  195.     if (_nr >> 4) {                    \
  196.         _tmp = (_nr >> 4) - 1;            \
  197.         asm volatile (                \
  198.             "1: "                \
  199.             "movew %0@+,%2@; "        \
  200.             "movew %0@+,%2@; "        \
  201.             "movew %0@+,%2@; "        \
  202.             "movew %0@+,%2@; "        \
  203.             "movew %0@+,%2@; "        \
  204.             "movew %0@+,%2@; "        \
  205.             "movew %0@+,%2@; "        \
  206.             "movew %0@+,%2@; "        \
  207.             "movew %0@+,%2@; "        \
  208.             "movew %0@+,%2@; "        \
  209.             "movew %0@+,%2@; "        \
  210.             "movew %0@+,%2@; "        \
  211.             "movew %0@+,%2@; "        \
  212.             "movew %0@+,%2@; "        \
  213.             "movew %0@+,%2@; "        \
  214.             "movew %0@+,%2@; "        \
  215.             "dbra %1,1b"               \
  216.             : "=a" (_buf), "=d" (_tmp)    \
  217.             : "a" (_port), "0" (_buf),    \
  218.               "1" (_tmp));            \
  219.     }                        \
  220. })
  221.  
  222. #ifdef CONFIG_ATARI
  223. #define insl_swapw(data_reg, buffer, wcount) \
  224.     insw_swapw(data_reg, buffer, (wcount)<<1)
  225. #define outsl_swapw(data_reg, buffer, wcount) \
  226.     outsw_swapw(data_reg, buffer, (wcount)<<1)
  227.  
  228. #define insw_swapw(port, buf, nr) \
  229.     if ((nr) % 8) \
  230.     __asm__ __volatile__ \
  231.            ("movel %0,%/a0; \
  232.          movel %1,%/a1; \
  233.          movel %2,%/d6; \
  234.          subql #1,%/d6; \
  235.            1:movew %/a0@,%/d0; \
  236.          rolw  #8,%/d0; \
  237.          movew %/d0,%/a1@+; \
  238.          dbra %/d6,1b" : \
  239.         : "g" (port), "g" (buf), "g" (nr) \
  240.         : "d0", "a0", "a1", "d6"); \
  241.     else \
  242.     __asm__ __volatile__ \
  243.            ("movel %0,%/a0; \
  244.          movel %1,%/a1; \
  245.          movel %2,%/d6; \
  246.          lsrl  #3,%/d6; \
  247.          subql #1,%/d6; \
  248.            1:movew %/a0@,%/d0; \
  249.          rolw  #8,%/d0; \
  250.          movew %/d0,%/a1@+; \
  251.          movew %/a0@,%/d0; \
  252.          rolw  #8,%/d0; \
  253.          movew %/d0,%/a1@+; \
  254.          movew %/a0@,%/d0; \
  255.          rolw  #8,%/d0; \
  256.          movew %/d0,%/a1@+; \
  257.          movew %/a0@,%/d0; \
  258.          rolw  #8,%/d0; \
  259.          movew %/d0,%/a1@+; \
  260.          movew %/a0@,%/d0; \
  261.          rolw  #8,%/d0; \
  262.          movew %/d0,%/a1@+; \
  263.          movew %/a0@,%/d0; \
  264.          rolw  #8,%/d0; \
  265.          movew %/d0,%/a1@+; \
  266.          movew %/a0@,%/d0; \
  267.          rolw  #8,%/d0; \
  268.          movew %/d0,%/a1@+; \
  269.          movew %/a0@,%/d0; \
  270.          rolw  #8,%/d0; \
  271.          movew %/d0,%/a1@+; \
  272.          dbra %/d6,1b" : \
  273.         : "g" (port), "g" (buf), "g" (nr) \
  274.         : "d0", "a0", "a1", "d6")
  275.  
  276. #define outsw_swapw(port, buf, nr) \
  277.     if ((nr) % 8) \
  278.     __asm__ __volatile__ \
  279.            ("movel %0,%/a0; \
  280.          movel %1,%/a1; \
  281.          movel %2,%/d6; \
  282.          subql #1,%/d6; \
  283.            1:movew %/a1@+,%/d0; \
  284.          rolw  #8,%/d0; \
  285.          movew %/d0,%/a0@; \
  286.          dbra %/d6,1b" : \
  287.         : "g" (port), "g" (buf), "g" (nr) \
  288.         : "d0", "a0", "a1", "d6"); \
  289.     else \
  290.     __asm__ __volatile__ \
  291.            ("movel %0,%/a0; \
  292.          movel %1,%/a1; \
  293.          movel %2,%/d6; \
  294.          lsrl  #3,%/d6; \
  295.          subql #1,%/d6; \
  296.            1:movew %/a1@+,%/d0; \
  297.          rolw  #8,%/d0; \
  298.          movew %/d0,%/a0@; \
  299.          movew %/a1@+,%/d0; \
  300.          rolw  #8,%/d0; \
  301.          movew %/d0,%/a0@; \
  302.          movew %/a1@+,%/d0; \
  303.          rolw  #8,%/d0; \
  304.          movew %/d0,%/a0@; \
  305.          movew %/a1@+,%/d0; \
  306.          rolw  #8,%/d0; \
  307.          movew %/d0,%/a0@; \
  308.          movew %/a1@+,%/d0; \
  309.          rolw  #8,%/d0; \
  310.          movew %/d0,%/a0@; \
  311.          movew %/a1@+,%/d0; \
  312.          rolw  #8,%/d0; \
  313.          movew %/d0,%/a0@; \
  314.          movew %/a1@+,%/d0; \
  315.          rolw  #8,%/d0; \
  316.          movew %/d0,%/a0@; \
  317.          movew %/a1@+,%/d0; \
  318.          rolw  #8,%/d0; \
  319.          movew %/d0,%/a0@; \
  320.          dbra %/d6,1b" : \
  321.         : "g" (port), "g" (buf), "g" (nr) \
  322.         : "d0", "a0", "a1", "d6")
  323.  
  324. #endif /* CONFIG_ATARI */
  325.  
  326. #define T_CHAR          (0x0000)        /* char:  don't touch  */
  327. #define T_SHORT         (0x4000)        /* short: 12 -> 21     */
  328. #define T_INT           (0x8000)        /* int:   1234 -> 4321 */
  329. #define T_TEXT          (0xc000)        /* text:  12 -> 21     */
  330.  
  331. #define T_MASK_TYPE     (0xc000)
  332. #define T_MASK_COUNT    (0x3fff)
  333.  
  334. #define D_CHAR(cnt)     (T_CHAR  | (cnt))
  335. #define D_SHORT(cnt)    (T_SHORT | (cnt))
  336. #define D_INT(cnt)      (T_INT   | (cnt))
  337. #define D_TEXT(cnt)     (T_TEXT  | (cnt))
  338.  
  339. #if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
  340. static u_short driveid_types[] = {
  341.     D_SHORT(10),    /* config - vendor2 */
  342.     D_TEXT(20),    /* serial_no */
  343.     D_SHORT(3),    /* buf_type, buf_size - ecc_bytes */
  344.     D_TEXT(48),    /* fw_rev - model */
  345.     D_CHAR(2),    /* max_multsect - vendor3 */
  346.     D_SHORT(1),    /* dword_io */
  347.     D_CHAR(2),    /* vendor4 - capability */
  348.     D_SHORT(1),    /* reserved50 */
  349.     D_CHAR(4),    /* vendor5 - tDMA */
  350.     D_SHORT(4),    /* field_valid - cur_sectors */
  351.     D_INT(1),    /* cur_capacity */
  352.     D_CHAR(2),    /* multsect - multsect_valid */
  353.     D_INT(1),    /* lba_capacity */
  354.     D_SHORT(194)    /* dma_1word - reservedyy */
  355. };
  356.  
  357. #define num_driveid_types       (sizeof(driveid_types)/sizeof(*driveid_types))
  358. #endif /* CONFIG_AMIGA */
  359.  
  360. static __inline__ void ide_fix_driveid(struct hd_driveid *id)
  361. {
  362. #if defined(CONFIG_AMIGA) || defined (CONFIG_MAC)
  363.    u_char *p = (u_char *)id;
  364.    int i, j, cnt;
  365.    u_char t;
  366.  
  367.    if (!MACH_IS_AMIGA && !MACH_IS_MAC)
  368.        return;
  369.    for (i = 0; i < num_driveid_types; i++) {
  370.       cnt = driveid_types[i] & T_MASK_COUNT;
  371.       switch (driveid_types[i] & T_MASK_TYPE) {
  372.          case T_CHAR:
  373.             p += cnt;
  374.             break;
  375.          case T_SHORT:
  376.             for (j = 0; j < cnt; j++) {
  377.                t = p[0];
  378.                p[0] = p[1];
  379.                p[1] = t;
  380.                p += 2;
  381.             }
  382.             break;
  383.          case T_INT:
  384.             for (j = 0; j < cnt; j++) {
  385.                t = p[0];
  386.                p[0] = p[3];
  387.                p[3] = t;
  388.                t = p[1];
  389.                p[1] = p[2];
  390.                p[2] = t;
  391.                p += 4;
  392.             }
  393.             break;
  394.          case T_TEXT:
  395.             for (j = 0; j < cnt; j += 2) {
  396.                t = p[0];
  397.                p[0] = p[1];
  398.                p[1] = t;
  399.                p += 2;
  400.             }
  401.             break;
  402.       }
  403.    }
  404. #endif /* CONFIG_AMIGA */
  405. }
  406.  
  407. static __inline__ void ide_release_lock (int *ide_lock)
  408. {
  409. #ifdef CONFIG_ATARI
  410.     if (MACH_IS_ATARI) {
  411.         if (*ide_lock == 0) {
  412.             printk("ide_release_lock: bug\n");
  413.             return;
  414.         }
  415.         *ide_lock = 0;
  416.         stdma_release();
  417.     }
  418. #endif /* CONFIG_ATARI */
  419. }
  420.  
  421. static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
  422. {
  423. #ifdef CONFIG_ATARI
  424.     if (MACH_IS_ATARI) {
  425.         if (*ide_lock == 0) {
  426.             if (in_interrupt() > 0)
  427.                 panic( "Falcon IDE hasn't ST-DMA lock in interrupt" );
  428.             stdma_lock(handler, data);
  429.             *ide_lock = 1;
  430.         }
  431.     }
  432. #endif /* CONFIG_ATARI */
  433. }
  434.  
  435. #define ide_ack_intr(hwif)    ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
  436.  
  437. /*
  438.  * On the Atari, we sometimes can't enable interrupts:
  439.  */
  440.  
  441. /* MSch: changed sti() to STI() wherever possible in ide.c; moved STI() def. 
  442.  * to asm/ide.h 
  443.  */
  444. /* The Atari interrupt structure strictly requires that the IPL isn't lowered
  445.  * uncontrolled in an interrupt handler. In the concrete case, the IDE
  446.  * interrupt is already a slow int, so the irq is already disabled at the time
  447.  * the handler is called, and the IPL has been lowered to the minimum value
  448.  * possible. To avoid going below that, STI() checks for being called inside
  449.  * an interrupt, and in that case it does nothing. Hope that is reasonable and
  450.  * works. (Roman)
  451.  */
  452. #ifdef MACH_ATARI_ONLY
  453. #define    ide__sti()                    \
  454.     do {                        \
  455.     if (!in_interrupt()) __sti();            \
  456.     } while(0)
  457. #elif defined(CONFIG_ATARI)
  458. #define    ide__sti()                        \
  459.     do {                            \
  460.     if (!MACH_IS_ATARI || !in_interrupt()) sti();        \
  461.     } while(0)
  462. #else /* !defined(CONFIG_ATARI) */
  463. #define    ide__sti()    __sti()
  464. #endif
  465.  
  466. #endif /* __KERNEL__ */
  467.  
  468. #endif /* _M68K_IDE_H */
  469.